package com.thot.timyag.core.pathwatch;

import java.io.File;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Observable;

import lombok.Getter;

import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;

/**
 * @author yangjf
 * @time 2019-04-11 16:00
 * 用于监控路径下的文件是否有变动，变动时通知订阅者
 */

public class PathWatcher extends Observable {

    @Getter
    private String watchPath;

    private int intervalSecond;

    public long lastMod;

    public PathWatcher(String watchPath, int intervalSecond) {
        this.watchPath = watchPath;
        this.intervalSecond = intervalSecond;
    }

    public void doWatch() {
        try {
            final Path path = FileSystems.getDefault().getPath(watchPath);
            final WatchService watchService = FileSystems.getDefault().newWatchService();
            path.register(watchService, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
            while (true) {
                final WatchKey wk = watchService.take();
                for (WatchEvent<?> event : wk.pollEvents()) {
                    WatchEvent.Kind<?> kind = event.kind();
                    if (kind == OVERFLOW) {
                        continue;
                    }
                    if (kind == ENTRY_DELETE) {
                        setChanged();
                    } else {
                        Path changed = (Path) event.context();
                        Path absolute = path.resolve(changed);
                        File configFile = absolute.toFile();
                        long lastModified = configFile.lastModified();
                        // 利用文件时间戳，防止触发两次
                        if (lastModified != lastMod && configFile.length() > 0) {
                            // 保存上一次时间戳
                            lastMod = lastModified;
                            setChanged();
                        }
                    }
                }

                if (hasChanged()) {
                    System.out.println("path" + this.watchPath + " files changed");
                    //通知订阅者
                    notifyObservers();
                }
                // reset the key
                boolean valid = wk.reset();
                if (!valid) {
                    System.out.println("watch key invalid!");
                    break;
                }
                //10秒刷新一次
                Thread.sleep(intervalSecond * 1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
